package com.baibei.pay.recharge;

import android.app.Dialog;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.InputFilter;
import android.text.TextUtils;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.webkit.WebView;
import android.widget.TextView;
import android.widget.Toast;

import com.alibaba.android.arouter.facade.annotation.Route;
import com.baibei.basic.IPresenter;
import com.baibei.ebec.sdk.ApiConstant;
import com.baibei.ebec.sdk.BuildConfig;
import com.baibei.ebec.sdk.TokenInfo;
import com.baibei.model.InoutFundParam;
import com.baibei.model.PayModeInfo;
import com.baibei.model.RechargeAmountInfo;
import com.baibei.model.UserInfo;
import com.baibei.module.AppRouter;
import com.baibei.module.BasicActivity;
import com.baibei.module.InoutFundParamProvider;
import com.baibei.module.OnItemSelectListener;
import com.baibei.pay.R;
import com.baibei.pay.R2;
import com.baibei.ui.AppUI;
import com.baibei.widget.CashierInputFilter;
import com.baibei.widget.RaeEditText;
import com.blankj.utilcode.utils.LogUtils;
import com.google.gson.Gson;
import com.rae.swift.Rx;
import com.rae.swift.session.SessionManager;
import com.tencent.mm.opensdk.modelpay.PayReq;
import com.tencent.mm.opensdk.openapi.IWXAPI;
import com.tencent.mm.opensdk.openapi.WXAPIFactory;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import okhttp3.Call;
import okhttp3.FormBody;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;


@Route(path = AppRouter.ROUTER_USER_RECHARGE)
public class RechargeActivity extends BasicActivity implements RechargeContract.RechrageView, OnItemSelectListener<RechargeAmountInfo> {

    @BindView(R2.id.tv_amount)
    TextView mTvAmount;
    @BindView(R2.id.et_recharge_count)
    RaeEditText mEtRechargeCount;
    @BindView(R2.id.tv_btn_recharge)
    TextView mBtnRecharge;
    @BindView(R2.id.tv_hint)
    TextView mTvHint;
    //    @BindView(R2.id.tv_fund_time)
//    TextView mTvFundTime;
    @BindView(R2.id.recycler_view)
    RecyclerView mAmountRecyclerView;
    @BindView(R2.id.wv)
    WebView wv;
    @BindView(R2.id.et_recharge_notice)
    TextView etRechargeNotice;
    private AmountAdapter mAmountAdapter;
    @BindView(R2.id.pay_recycler_view)
    RecyclerView mPayRecyclerView;
    private PayModeAdapter mPayModeAdapter;
    private String mDeviceId;
    private int ALI_WEB_PAY = 1;
    private int WX_WEB_PAY = 2;

    /**
     * 表现层
     */
    private RechargeContract.Presenter mPresenter;


    /**
     * 最大金额
     * 最小金额
     */
    public static final int MAX_AMOUNT = Integer.MAX_VALUE;
    double mMinAmount;

    /**
     * 选中位置
     */
    private int mSelectPosition;

    /**
     * lock
     */
    private final Object mLock = new Object();
    private String codeImgUrl;
    private String codeUrl;
    private JSONObject json;
    private JSONObject job;
    private TokenInfo userToken;
    private String ip;
    private UserInfo userInfo;
    private String helpContent;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_recharge);
        EventBus.getDefault().register(this);
        ButterKnife.bind(this);
        mPresenter = inject(RechargeContract.Presenter.class);
        userToken = SessionManager.getDefault().getUserToken();
        userInfo = SessionManager.getDefault().getUser();
        initView();
    }

    @Subscribe
    public void onSuccess(SuccessEvent event) {
        //充值成功回调
        finish();
    }

    @Override
    protected void onDestroy() {
        EventBus.getDefault().unregister(this);
        super.onDestroy();
    }

    @Override
    protected void onResume() {
        super.onResume();
        //刷新余额
        mPresenter.getBalance();
    }

    private void initView() {

        //推荐金额
        mAmountRecyclerView.setLayoutManager(new GridLayoutManager(this, 3));
        mAmountRecyclerView.getItemAnimator().setChangeDuration(0);
        mAmountAdapter = new AmountAdapter();
        mAmountAdapter.setOnItemSelectListener(this);
        mAmountRecyclerView.setAdapter(mAmountAdapter);

        //支付方式
        mPayRecyclerView.setLayoutManager(new LinearLayoutManager(this));
        mPayModeAdapter = new PayModeAdapter();
        mPayModeAdapter.setListener(new OnPayModeListener());
        mPayRecyclerView.setAdapter(mPayModeAdapter);

        //监听数量变化，进行设置按钮是否开启
        mEtRechargeCount.addTextChangedListener(mInputListener);

        CashierInputFilter cashierInputFilter = new CashierInputFilter();
        cashierInputFilter.setMaxValue(MAX_AMOUNT);
        InputFilter[] inputFilter = {cashierInputFilter};
        mEtRechargeCount.setFilters(inputFilter);

        //获取基本信息
        mPresenter.getRechargeInfo();
        mPresenter.getHelp();

        //获取ip
        new Thread(new Runnable() {

            @Override
            public void run() {
                String ipJson = getIP(getContext());
                try {
                    JSONObject job = new JSONObject(ipJson);
                    ip = job.optString("ip");
                } catch (JSONException e) {
                    e.printStackTrace();
                    ToastOnUiThread("网络错误，请重试");
                    return;
                }
            }
        }).start();
    }


    @Override
    public IPresenter getBasicPresenter() {
        return mPresenter;
    }

    @OnClick(R2.id.tv_btn_recharge)
    public void onViewClicked() {
        final UserInfo userInfo = SessionManager.getDefault().getUser();
        if (userInfo == null) {
            AppRouter.routeToLogin(this);
            return;
        }
        if (mAmountAdapter.getInfos() == null || mPayModeAdapter.getInfos() == null) {
            return;
        }
        final InoutFundParam param = InoutFundParamProvider.get();

        //设置金额
        for (RechargeAmountInfo info : mAmountAdapter.getInfos()) {
            if (info.isSelect()) {
                param.setAmount(info.getAmount());
            }
        }
        if (!TextUtils.isEmpty(mEtRechargeCount.getEditableText().toString())) {
            param.setAmount(Rx.parseDouble(mEtRechargeCount.getEditableText().toString()));
        }
        //设置支付渠道

        final double amount = param.getAmount();
        for (final PayModeInfo info : mPayModeAdapter.getInfos()) {
            if (info.isSelect()) {
                if ("201".equals(info.getId())) {
                    if (!isAppChatExist("com.eg.android.AlipayGphone")) {
                        Toast.makeText(getContext(), "请安装支付宝客户端", Toast.LENGTH_LONG).show();
                        return;
                    }
                    //支付宝支付
                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            webPay(ALI_WEB_PAY, amount, info.getPayUrl());
                        }
                    }).start();
                    return;
                }

                if ("401".equals(info.getId())) {
                    //微信客户端支付
                    IWXAPI wxapi = WXAPIFactory.createWXAPI(this, com.baibei.module.BuildConfig.WECHAT_APP_ID);
                    if ((!wxapi.isWXAppInstalled() || !wxapi.isWXAppSupportAPI()) && !isAppChatExist("com.tencent.mm")) {
                        Toast.makeText(getContext(), "请安装微信客户端", Toast.LENGTH_LONG).show();
                        return;
                    }
                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            wxPay(amount, info.getPayUrl());
                        }
                    }).start();
                    return;
                }

                if ("501".equals(info.getId())) {
                    //微信网页支付
                    if (!isAppChatExist("com.tencent.mm")) {
                        Toast.makeText(getContext(), "请安装微信客户端", Toast.LENGTH_LONG).show();
                        return;
                    }
                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            webPay(WX_WEB_PAY, amount, info.getPayUrl());
                        }
                    }).start();
                    return;
                }
                if ("601".equals(info.getId())) {
                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            HXPay(amount, info, param);
                        }
                    }).start();
                    return;
                }
                if ("701".equals(info.getId())) {
                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            webPay(ALI_WEB_PAY, amount, info.getPayUrl());
                        }
                    }).start();
                    return;
                }

                param.setUrl(info.getPayUrl());
                param.setPayModeInfo(info);

//                Log.i("hhhhhhhh",param.toString());
            }
        }
        AppRouter.routeRechargeWeb(this, param);
    }

    private void HXPay(double amount, PayModeInfo info, InoutFundParam param) {

        String url = info.getPayUrl() + "?userId=" + userInfo.getUserId() + "&accessToken=" + userToken.getAccessToken() + "&amount=" + amount;
//        AppRouter.routeToWeb(this,"环迅支付",url);
//        Intent intent = new Intent(RechargeActivity.this, HXPayWebViewActivity.class);
//        intent.putExtra("url",url);
//        intent.putExtra("title","环迅支付");
//        startActivity(intent);
        param.setUrl(url);
        param.setPayModeInfo(info);
        AppRouter.routeRechargeWeb(this, param);

    }

    private boolean isAppChatExist(String packageName) {
        final PackageManager packageManager = getContext().getPackageManager();
        List<PackageInfo> pinfo = packageManager.getInstalledPackages(0);
        if (pinfo != null) {
            for (int i = 0; i < pinfo.size(); i++) {
                String pn = pinfo.get(i).packageName;
                if (pn.equals(packageName)) {
                    return true;
                }
            }
        }
        return false;
    }

    private void wxPay(double amount, String payUrl) {

        OkHttpClient client = new OkHttpClient();
        String str = reqBody(amount);

        RequestBody requestBody = FormBody.create(MediaType.parse("application/json; charset=utf-8"), str);
        Request request = new Request.Builder()
                .url(payUrl)
                .post(requestBody)
                .build();
        Call call = client.newCall(request);
        try {
            Response response = call.execute();
            JSONObject jsonObject = new JSONObject(response.body().string());
            String code = jsonObject.optString("code");
            String message = jsonObject.optString("message");
            if (!"SUCCESS".equals(code)) {
                ToastOnUiThread(message);
                return;
            }
            JSONObject job = jsonObject.optJSONObject("data");
            String token = job.optString("token");
            String appid = job.optString("appid");
            String partnerid = job.optString("partnerid");
            String noncestr = job.optString("noncestr");
            String timestamp = job.optString("timestamp");
            String sign = job.optString("sign");

            toWxPay(token, appid, partnerid, noncestr, timestamp, sign);

        } catch (IOException e) {
            e.printStackTrace();
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    private void toWxPay(String token, String appid, String partnerid, String noncestr, String timestamp, String sign) {
        IWXAPI wxapi = WXAPIFactory.createWXAPI(this, appid);
        wxapi.registerApp(appid);
        PayReq request = new PayReq();
        request.appId = appid;
        request.partnerId = partnerid;
        request.prepayId = token;
        request.packageValue = "Sign=WXPay";
        request.nonceStr = noncestr;
        request.timeStamp = timestamp;
        request.sign = sign;
        Log.i("wxpay", request.checkArgs() + "");
        Log.i("wxpay", appid + " " + partnerid + " " + token + " " + noncestr + " " + timestamp + " " + sign);

        wxapi.registerApp(appid);
        wxapi.sendReq(request);

    }

    private void webPay(int type, double amount, String payUrl) {
        OkHttpClient client = new OkHttpClient();
        String str = reqBody(amount);
        RequestBody requestBody = FormBody.create(MediaType.parse("application/json; charset=utf-8"), str);
        Request request = new Request.Builder()
                .url(payUrl)
                .post(requestBody)
                .build();
        Call call = client.newCall(request);
        try {
            Response response = call.execute();
            String s = response.body().string();
            job = new JSONObject(s);
        } catch (Exception e) {
            e.printStackTrace();
            ToastOnUiThread("充值失败");
            return;
        }
        String code = job.optString("code");
        String message = job.optString("message");
        if (!"SUCCESS".equals(code)) {
            ToastOnUiThread(message);
            return;
        }
        JSONObject json = job.optJSONObject("data");
        String codeImgUrl = json.optString("codeImgUrl", null);
        String codeUrl = json.optString("codeUrl", null);
        LogUtils.e("urlsss", codeUrl);
        LogUtils.e("urlssss", payUrl);
        if (codeUrl == null) {
            ToastOnUiThread("该充值渠道暂不可用");
            return;
        }
        Intent intent = new Intent(RechargeActivity.this, WebPayActivity.class);
//        intent.putExtra("title", type == ALI_WEB_PAY ? "支付宝扫码支付" : "微信扫码支付");
        intent.putExtra("type", type);
        intent.putExtra("codeImgUrl", codeImgUrl);
        intent.putExtra("codeUrl", codeUrl);
        startActivity(intent);
    }

    private void ToastOnUiThread(final String s) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                Toast.makeText(getApplicationContext(), s, Toast.LENGTH_LONG).show();
            }
        });
    }

    private String reqBody(double amount) {
        HashMap<String, String> data = new HashMap<>();
        data.put("amount", "" + amount);
        data.put("userIp", ip);
        HashMap<String, Object> map = new HashMap<>();
        map.put("exchange", BuildConfig.EXCHANGE);
        map.put("requestId", UUID.randomUUID().toString());
        if (SessionManager.getDefault().getUser() != null) {
            map.put("userId", ((UserInfo) SessionManager.getDefault().getUser()).getUserId() + "");
        } else {
            map.put("userId", "0");
        }
        map.put("platform", "server");
        map.put("deviceId", getDeviceId());
        map.put("timestamp", "" + System.currentTimeMillis());
        map.put("version", getVersion());
        map.put("memberChannel", ApiConstant.MEMBER_CHANNEL);
        map.put("appKey", BuildConfig.APPKEY);
        map.put("accessToken", userToken.getAccessToken());
        map.put("refreshToken", userToken.getRefreshToken());
        map.put("data", data);

        Gson gson = new Gson();
        String str = gson.toJson(map);

        return str;
    }


    public static String getIP(Context context) {
        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder().url("https://api.ipify.org?format=json").build();
        Call call = client.newCall(request);
        try {
            Response response = call.execute();
            String ip = response.body().string();
            return ip;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return "";
    }

    private String getVersion() {
        try {
            return getPackageManager().getPackageInfo(getPackageName(), PackageManager.GET_META_DATA).versionName;
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
            return "1.0.0";
        }
    }


    @Override
    public void onLoadBalance(double balance) {
        mTvAmount.setText(String.valueOf(Rx.formatPrice(balance)) + "元");
    }

    @Override
    public void onLoadBalanceFailed(String msg) {
        AppUI.failed(this, msg);
    }

    @Override
    public void showLoading() {
        AppUI.loading(this);
    }

    @Override
    public void hideLoading() {
        AppUI.dismiss();
    }

    @Override
    public void onShowFundTimeInfo(String msg) {
//        mTvFundTime.setText(msg);
    }

    @Override
    public void onLoadRechargeAmount(List<RechargeAmountInfo> list) {
        for (int i = 0; i < list.size(); i++) {
            list.get(i).setSelect(i == 0);
        }
        mAmountAdapter.setInfos(list);

        mAmountAdapter.notifyDataSetChanged();


    }

    @Override
    public void onLoadMinAmount(double min) {
        //debug模式，不进行限制
        mMinAmount = min;
        mEtRechargeCount.setHint("其他金额(" + Rx.formatPrice(min) + "元起)");
    }

    @Override
    public void onLoadPayModeList(List<PayModeInfo> list) {
        for (int i = 0; i < list.size(); i++) {
            list.get(i).setSelect(i == 0);
        }

        //默认选中第一项，设置自定义框是否显示
        if ("1".equals(list.get(0).getState())) {
            etRechargeNotice.setVisibility(View.GONE);
            mEtRechargeCount.setVisibility(View.VISIBLE);
        }

        mPayModeAdapter.setInfos(list);
        mPayModeAdapter.notifyDataSetChanged();

    }

    @Override
    public void onLoadBasicInfoFailed(String msg) {
        AppUI.failed(this, msg);
    }

    @Override
    public void onLoadHelpSuccess(String s) {
        helpContent = s;
    }


    @Override
    public void onItemSelectListener(View view, RechargeAmountInfo rechargeAmountInfo, int position) {
        //如果已经选中，停止操作
        synchronized (mLock) {
            if (rechargeAmountInfo.isSelect()) {
                return;
            }
            //更新选中
            for (RechargeAmountInfo info : mAmountAdapter.getInfos()) {
                info.setSelect(info == rechargeAmountInfo);
            }
            mAmountAdapter.notifyDataSetChanged();
            //记录坐标，用于还原操作
            mSelectPosition = position;

            //充值金额输入为空
            mEtRechargeCount.removeTextChangedListener(mInputListener);
            mEtRechargeCount.setText(null);
            mEtRechargeCount.addTextChangedListener(mInputListener);

            //还原操作
            mBtnRecharge.setEnabled(true);
            mTvHint.setText(null);
        }
    }

    @OnClick(R2.id.iv_help)
    public void onHelpClicked() {
        popHelpDialog();
    }

    private void popHelpDialog() {
        Dialog helpDialog = new Dialog(this, R.style.HelpDialog);
        Window window = helpDialog.getWindow();
        window.requestFeature(Window.FEATURE_NO_TITLE);
        window.setGravity(Gravity.RIGHT | Gravity.TOP);
        helpDialog.setContentView(com.baibei.ebec.home.R.layout.dialog_pop_help);
        WindowManager.LayoutParams lp = window.getAttributes();
        lp.x = dip2px(this, 27);
        lp.y = dip2px(this, 39);
        TextView tvHelp = helpDialog.findViewById(com.baibei.ebec.home.R.id.tv_help);

        if (helpContent == null) {
            tvHelp.setText("\n1.  充值时间为9：00-21：00，节假日除外，单笔充值金额最低10元\n\n" +
                    "2.  提现时间为9：00-21：00，节假日除外\n\n" +
                    "3.  客户提现金额不满100元时，需承担2元/笔的提现手续费，提现需满足有一笔现金订购\n");
        } else {
            tvHelp.setText(helpContent + "\n");
        }
        helpDialog.show();
    }


    /**
     * 选择支付方式回调
     */
    private class OnPayModeListener implements OnItemSelectListener<PayModeInfo> {

        @Override
        public void onItemSelectListener(View view, PayModeInfo payModeInfo, int position) {
            if (payModeInfo.isSelect()) {
                return;
            }
            for (PayModeInfo info : mPayModeAdapter.getInfos()) {
                info.setSelect(info == payModeInfo);
                if ("1".equalsIgnoreCase(payModeInfo.getState())) {
                    etRechargeNotice.setVisibility(View.GONE);
                    mEtRechargeCount.setVisibility(View.VISIBLE);
                } else {
                    mEtRechargeCount.setVisibility(View.GONE);
                    etRechargeNotice.setVisibility(View.VISIBLE);
                }
            }
            mPayModeAdapter.notifyDataSetChanged();
        }
    }

    /**
     * 监听输入操作
     */
    private SimpleTextWatcher mInputListener = new SimpleTextWatcher() {
        @Override
        public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
            mBtnRecharge.setEnabled(true);
            if (TextUtils.isEmpty(charSequence)) {
                mTvHint.setText(null);
            } else if (!(Rx.parseDouble(charSequence) >= mMinAmount && Rx.parseDouble(charSequence) <= MAX_AMOUNT)) {
                mTvHint.setText(String.format("温馨提示：充值金额至少%s元", Rx.formatPrice(mMinAmount)));
                mBtnRecharge.setEnabled(false);
            } else {
                //可以充值
                mTvHint.setText(null);
            }
            //是否清空选中
            clearSelect(!TextUtils.isEmpty(charSequence));
        }
    };

    /**
     * 是否清空选中
     */
    private void clearSelect(boolean isClear) {
        List<RechargeAmountInfo> infos = mAmountAdapter.getInfos();
        if (infos != null && infos.size() - 1 >= mSelectPosition) {
            infos.get(mSelectPosition).setSelect(!isClear);
            mAmountAdapter.notifyItemChanged(mSelectPosition);
        }
    }

    private String getDeviceId() {
//        // 有值直接返回
//        if (!TextUtils.isEmpty(mDeviceId)) return mDeviceId;
//        // 从配置文件中获取
//        mDeviceId = mConfig.getDeviceId();

        // 如果为空，自动生产
//        if (TextUtils.isEmpty(mDeviceId)) {
        // BB-时间戳-UUID
        mDeviceId = "BB-" + System.currentTimeMillis() + "-" + UUID.randomUUID().toString();
//            mConfig.setDeviceId(mDeviceId);
//        }

        return mDeviceId;
    }

    public static int dip2px(Context context, float dipValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dipValue * scale + 0.5f);
    }

}
